/* 
      ------分数注意事项-----
      本次测试满分为100(最多100分), 有4道加分题; 答案不够完整或者有错误当题0分处理; 

      ------分数处理-----
      (0-60]: 不及格, 处理: 提供第二份不同试卷晚自习的时候重新考试, 并在第二天晚自习时间单独进行测试题提问(大部分都回答不上则采用手抄试卷方案);

      (60-75]: 良良, 处理: 晚自习时间单独进行测试题提问(大部分都回答不上则采用手抄试卷方案);

      (75-90]: 良好, 处理: 放你一马, 好好复习;

      (90-100]: 优秀, 处理: 好好好, 继续保持;
      */

// 1.JS延迟加载的方式有哪些？（5）
// setTimeout();

// 2.前端 JavaScript 中的 ECMAScript、DOM、BOM 的含义；（5）
/*
        EMCAScript ECMA 组织定制一套标准
        DOM 文档对象模型（document object model）
        BOM 浏览器对象模型（browser object model）
      */

// 4.如何进行数据类型的判断？（5）
/*
        Object.prototype.toString.call()
        instanceof()
        typeof()
      */

// 5.null 和 undefined 的区别？什么时候会得到 undefined？（5）
/*
       NULL 是变量为空或不含任何值，空的值/对象/对象引用地址，
       undefined 表示变量已声明但未赋值
       函数的默认返回值是 undefined，对象不存在属性时，也返回undefined
      */

// 6.如何理解 null == undefined 返回 true，null === undefined 返回 false？（5）
/*
        == 不判断数据类型，null和undefined，隐性转换数据类型后，都表示一个无效的值，所以null == undefined 返回true
        === 判断数据类型 不会自动转换为数据类型，所以返回false
      */

// 7.使用 continue 或 break 终止循环时，两种方式的区别是？（5）
/*
        continue 跳出当前符合条件的流程,继续下一个流程
        break 中断整个流程控制
      */

// 8.如何判断字符串内是否包含指定字符？（5）
/*
        let str = [1, 2, 3];
        str.includes("1"); // 返回布尔值
        str.indexOf(str[i]) != -1; // 找不到返回-1
        for循环遍历;
      */

// 9.请尽量列举出数组的方法，并且注明哪些方法会修改原数组，哪些不会；（5）
/*
        改变原数组：
          arr.push()
          arr.reverse()
          arr.splice()
          arr.pop()
          arr.shift()
          arr.unshift()
        不会修改原数组
          arr.join()
          arr.concat()
          arr.slice()
          arr.indexOf()
          arr.lastIndexOf()
          arr.includes()
      */

// 10. 请写出下面语句的输出结果：（5）
// let bar = true, number = 0;
// console.log(bar + 0);  // 1
// console.log(bar + "xyz"); // truexyz
// console.log(bar + true); // 2
// console.log(+true); // 1
// console.log(!'bluej'); // false
// console.log(number++); // 0
// console.log(++number); // 2
// console.log(number); // 2

// 11. 根据用户输入时间实现倒计时，输入时间格式错误时要有错误提示（5）
// window.prompt("请输入目标时间");
let t = new Date(window.prompt('请输入目标时间')).getTime();
function f11(t) {
  t = t - Date.now();
  if (t <= 0) {
    alert('输入错误');
  } else {
    let D, h, m, s;
    t = parseInt(t / 1000);
    D = parseInt(t / 60 / 60 / 24);
    h = parseInt((t / 60 / 60) % 24);
    m = parseInt((t / 60) % 60);
    s = parseInt(t % 60);

    if (t > 0) {
      console.clear();
      console.log(`距离倒计时结束还有:${D}天${h}时${m}分${s}秒`);
    } else {
      console.log('凳等!你来晚了');
    }
  }
}
let timer = setInterval(function () {
  f11(t);
}, 1000);
// 12.输出从小到大排序好的五个不重复的随机"素数",范围[10-58)；（10）
// 质数也叫素数是指在大于1的自然数中，除了1和它本身以外不再有其他因数的自然数，不能被任何整数整除的数。
function f12() {
  let arr = [],
    num;
  while (arr.length < 5) {
    num = Math.floor(Math.random() * (58 - 10) + 10);
    let isPrime = true;
    for (let i = 2; i <= Math.sqrt(num); i++) {
      if (num % i === 0) {
        isPrime = false;
        break;
      }
    }
    if (isPrime && !arr.includes(num)) {
      arr.push(num);
    }
  }
  arr.sort((a, b) => a - b);
  return arr;
}
console.log(f12());
// 13.把下面数组成员排序打乱；（5）
let arr13 = [10, 20, 30, 40, 50, 60];
let newArr2 = []; // 打乱之后的数组

function f13(arr) {
  while (newArr2.length < arr.length) {
    let num = Math.floor(Math.random() * arr.length);
    if (!newArr2.includes(arr[num])) {
      newArr2.push(arr[num]);
    }
  }
  return newArr2;
}
console.log(f13(arr13));

// 14. 将多个数组进行去重合并；（10）
let arr140 = [1, 2, 3],
  arr141 = [2, 3, 4, 5];
function f14(arr1, arr2) {
  for (let i = 0; i < arr1.length; i++) {
    if (!arr2.includes(arr1[i])) {
      arr2.push(arr1[i]);
    }
  }
  return arr2.sort((a, b) => a - b);
}
console.log(f14(arr140, arr141));
// 15. 找出数组 arr=[1, 2, 3, "a", 4, "a", 2, 4, "a"] 中重复出现过的元素,并用数组将重复元素装起来输出,并且统计每个元素出现的次数（10）

let arr15 = [1, 2, 3, 'a', 4, 'a', 2, 4, 'a'];
function f15(arr) {
  let obj = {};
  let obj2 = {};
  for (let i = 0; i < arr.length; i++) {
    if (obj[arr[i]] === undefined) {
      obj[arr[i]] = 1;
    } else {
      obj[arr[i]]++;
    }
  }
  for (let key in obj) {
    if (obj[key] > 1) {
      obj2[key] = obj[key];
    }
  }
  return obj2;
}
console.log(f15(arr15));
// 16. 找出数组中年龄小于18岁的女生的信息重新组成新的数组,并且将她们count变为现有的平方（10）
let arr16 = [
  {
    name: '111',
    sex: 'boy',
    age: 18,
    count: 20,
  },
  {
    name: '222',
    sex: 'girl',
    age: 17,
    count: 30,
  },
  {
    name: '333',
    sex: 'boy',
    age: 16,
    count: 40,
  },
  {
    name: '444',
    sex: 'girl',
    age: 15,
    count: 50,
  },
  {
    name: '555',
    sex: 'boy',
    age: 20,
    count: 60,
  },
  {
    name: '666',
    sex: 'girl',
    age: 13,
    count: 70,
  },
  {
    name: '777',
    sex: 'boy',
    age: 14,
    count: 80,
  },
];
function f16(arr) {
  let newArr = [];
  for (var i = 0; i < arr.length; i++) {
    if (arr[i].age < 18 && arr[i].sex === 'girl') {
      newArr.push(arr[i]);
    }
  }
  for (var i = 0; i < newArr.length; i++) {
    newArr[i].count *= newArr[i].count;
  }
  return newArr;
}
console.log(f16(arr16));
// 17. 实现一个深克隆函数 (加分题 5)
function clone(v) {
  if (Object.prototype.toString.call(v) === '[object Function]') {
    return v;
  }
  let res = Array.isArray(v) ? [] : {};
  for (const k in v) {
    // instanceof --> object、array
    if (v[k] instanceof Object) {
      res[k] = clone(v[k]);
    } else {
      res[k] = v[k];
    }
  }
  return res;
}
// 18. 实现一个数组的reduce方法 (加分题 5)

// 19. 写出强制转换的方法有哪些 (加分题 5)
// String(num);
// num.toString();
// Number(num);
// Boolean(num);
// parseInt(num);
// parseFloat(num);
// 20. 如何判断一个对象是否为空对象的3种方法 (加分题 5)
function f20(obj) {
  return Object.keys(obj).length === 0; // 判断对象所有key的数组是否等于0
}
function f20_1(obj) {
  return JSON.stringify(obj) === '{}'; // 判断序列化后是否是{}，如果是就是空对象
}
